from debug import *
from random import randint

buffer_size = 2
write_back_time = 600
read_time = 200

nfc_count = 2

recssd_time = 23 #us

matcher_time = 150

arm_time = 150

resource = {}
resource["host"] = 0
resource["arm"] = 0

for i in range(nfc_count):
    resource["nfc"+str(i)] = 0

resource["matcher1"] = 0
resource["matcher2"] = 0

matcher_count = len(list(filter(lambda x:True if "matcher" in x else False,list(resource))))

line_limit = 10
file_range = 1
max_file_index = 400

slacker_file_range = 10000

task_list = []

# ####################################添加写trace#############
# task = []
# stage_count = 1
# task.append("Write"+str(i))

# fd = open("trace/write/write.txt")
# line = fd.readline()

# #上次写的page（因为有很多重复的）
# last_lpn = -1
# line_count = 0
# while line!="":
#     lpn = int(line[1:].split("]")[0])
#     if lpn == last_lpn:
#         line = fd.readline()
#         continue

#     line_count += 1
#     if line_count >= line_limit:
#         break

#     last_lpn = lpn
#     nfc = lpn%nfc_count
#     page = round(lpn/nfc_count)

#     task.append([stage_count,"nfc"+str(nfc),read_time,(stage_count-1,),(nfc,page)])
#     stage_count += 1
#     task.append([stage_count,"arm",1,(stage_count-1,)])
#     stage_count += 1

#     line = fd.readline()

# #pre_stage = list(range(2,stage_count-1))

# task.append([stage_count,"host",20,(stage_count-1,)]) #返回结果

# task_list.append(task)

# fd.close()

recssd_count = 0
def generate_recssd_task():
    global recssd_count
    recssd_count += 1 
    file_index = randint(1,max_file_index-1) #留一个给400，不然+1就超了
    for i in range(file_index,file_index+file_range):
        #####################################################添加ndp trace
        #一个文件就是一条指令
        task = []
        stage_count = 1
        task.append("RecSSD"+str(i))
        task.append([stage_count,"host",20,(0,)])  #接受参数
        stage_count += 1

        fd = open("trace/ndp/ndp_read_"+str(i)+".txt")
        line = fd.readline()
        line_count = 0
        while line!="":
            line_count += 1
            if line_count >= line_limit:
                break
            
            lpn = int(line[1:].split("]")[0])
            nfc = lpn%nfc_count
            page = round(lpn/nfc_count)

            task.append([stage_count,"nfc"+str(nfc),read_time,(stage_count-1,),(nfc,page)])
            stage_count += 1
            task.append([stage_count,"arm",1,(stage_count-1,)])
            stage_count += 1
            task.append([stage_count,"arm",recssd_time,(stage_count-1,)])
            stage_count += 1

            line = fd.readline()

        #pre_stage = list(range(2,stage_count-1))

        task.append([stage_count,"host",20,(stage_count-1,)]) #返回结果

        fd.close()

    return task

recssd_read_count = 0
def generate_recssd_read_task():
    global recssd_read_count
    recssd_read_count += 1
    file_index = randint(1,max_file_index-1) #留一个给400，不然+1就超了
    for i in range(file_index,file_index+file_range):
        ##########################################添加读trace
        task = []
        stage_count = 1
        task.append("Read"+str(i))

        fd = open("trace/read/base_read_"+str(i)+".txt")
        line = fd.readline()
        line_count = 0
        while line!="":
            line_count += 1
            if line_count >= line_limit:
                break

            lpn = int(line[1:].split("]")[0])
            nfc = lpn%nfc_count
            page = round(lpn/nfc_count)

            task.append([stage_count,"nfc"+str(nfc),read_time,(stage_count-1,),(nfc,page)])
            stage_count += 1
            task.append([stage_count,"arm",1,(stage_count-1,)])
            stage_count += 1

            line = fd.readline()

        #pre_stage = list(range(2,stage_count-1))

        task.append([stage_count,"host",20,(stage_count-1,)]) #返回结果

        fd.close()

    return task

###########################生成随机负载#################################
#每种可能操作的地址范围，因为假设任务间没有依赖所以读、文本的范围和写的范围没有重叠
read_range = (0,10000)
text_search_range = (0,10000)
write_range = (10000,20000)

read_count = 0
def read_generator():
    global read_count
    read_count += 1

    task = []
    task.append("读"+str(read_count))

    ch = randint(0,nfc_count-1) #选择这次读哪个channel的数据
    page = randint(read_range[0],read_range[1])
    task.append([1,"nfc"+str(ch),read_time,(0,),(ch,page)])
    task.append([2,"arm",1,(1,)])
    task.append([3,"host",20,(2,),(ch,page)])
    
    return task

write_count = 0
def write_generator():
    global write_count
    write_count += 1

    task = []
    task.append("写"+str(write_count))

    page = randint(write_range[0],write_range[1])
    ch = randint(0,nfc_count-1) #选择这次读哪个channel的数据
    task.append([1,"nfc"+str(ch),read_time,(0,),(ch,page)])
    task.append([2,"arm",1,(1,)])
    task.append([3,"host",20,(2,),(ch,page)]) #告诉一下写的host操作应该操作哪个buffer（这方法太挫了，罪过罪过。。。）
    
    return task

def slacker_read_generator():
    global read_count
    read_count += 1

    task = []
    task.append("读"+str(read_count))

    stage_count = 1
    task.append([stage_count,"host",20,(0,)])  #接受参数
    stage_count += 1

    file_number = randint(0,slacker_file_range)
    fd = open("trace/seperated_blktrace/read/"+str(file_number)+".log")

    line = fd.readline()
    line_count = 0
    while line!="":
        line_count += 1
        if line_count >= line_limit:
            break

        #去掉最后的\n
        lpn = int(line[:-1])
        nfc = lpn%nfc_count
        page = round(lpn/nfc_count)

        task.append([stage_count,"nfc"+str(nfc),read_time,(stage_count-1,),(nfc,page)])
        stage_count += 1
        task.append([stage_count,"arm",1,(stage_count-1,)])
        stage_count += 1

        line = fd.readline()

    #pre_stage = list(range(2,stage_count-1))

    task.append([stage_count,"host",20,(stage_count-1,)]) #返回结果

    fd.close()
    
    return task

def slacker_write_generator():
    global write_count
    write_count += 1

    task = []
    task.append("写"+str(write_count))

    stage_count = 1
    task.append([stage_count,"host",20,(0,)])  #接受参数
    stage_count += 1

    file_number = randint(0,slacker_file_range)
    fd = open("trace/seperated_blktrace/write/"+str(file_number)+".log")

    line = fd.readline()
    line_count = 0
    while line!="":
        line_count += 1
        if line_count >= line_limit:
            break

        #去掉最后的\n
        lpn = int(line[:-1])
        nfc = lpn%nfc_count
        page = round(lpn/nfc_count)

        task.append([stage_count,"nfc"+str(nfc),read_time,(stage_count-1,),(nfc,page)])
        stage_count += 1
        task.append([stage_count,"arm",1,(stage_count-1,)])
        stage_count += 1

        line = fd.readline()

    #pre_stage = list(range(2,stage_count-1))

    task.append([stage_count,"host",20,(stage_count-1,)]) #返回结果

    fd.close()
    
    return task

text_search_count = 0
def text_search_generator():
    global text_search_count
    text_search_count += 1

    task = []
    task.append("文本"+str(text_search_count))

    ch0 = randint(0,nfc_count-1)
    ch1 = randint(0,nfc_count-1)
    ch2 = randint(0,nfc_count-1)
    ch3 = randint(0,nfc_count-1)
    ch4 = randint(0,nfc_count-1)

    page1 = randint(text_search_range[0],text_search_range[1])
    page2 = randint(text_search_range[0],text_search_range[1])
    page3 = randint(text_search_range[0],text_search_range[1])
    page4 = randint(text_search_range[0],text_search_range[1])
    page5 = randint(text_search_range[0],text_search_range[1])

    task.append([1,"host",20,(0,)])  #接受参数
    task.append([2,"nfc1",read_time,(1,),(1,page1)]) #获取元数据，假设元数据都在同一个块中
    task.append([3,"arm",1,(2,)])
    task.append([4,"nfc"+str(ch1),read_time,(3,),(ch1,page2)]) #读数据块
    task.append([5,"arm",1,(4,)])
    task.append([6,"matcher",matcher_time,(5,)]) #进行匹配
    task.append([7,"nfc"+str(ch2),read_time,(6,),(ch2,page3)])
    task.append([8,"arm",1,(7,)])
    task.append([9,"matcher",matcher_time,(8,)])
    task.append([10,"host",20,(6,9)])
    # task.append([11,"arm",20,(3,)])

    # task.append([1,"host",20,(0,)])  #接受参数

    # task.append([2,"nfc"+str(ch0),read_time,(1,),(ch0,page1)]) #获取元数据，假设元数据都在同一个块中
    # task.append([3,"arm",1,(2,)])
    # task.append([4,"arm",20,(3,)])

    # task.append([5,"nfc"+str(ch1),read_time,(4,),(ch1,page2)]) #读数据块
    # task.append([6,"arm",1,(5,)])
    # task.append([7,"matcher",matcher_time,(6,)]) #进行匹配
    
    # task.append([8,"nfc"+str(ch2),read_time,(4,),(ch2,page3)])
    # task.append([9,"arm",1,(8,)])
    # task.append([10,"matcher",matcher_time,(9,)])

    # task.append([11,"nfc"+str(ch2),read_time,(4,),(ch3,page4)])
    # task.append([12,"arm",1,(11,)])
    # task.append([13,"matcher",matcher_time,(12,)])

    # task.append([14,"nfc"+str(ch2),read_time,(4,),(ch4,page5)])
    # task.append([15,"arm",1,(14,)])
    # task.append([16,"matcher",matcher_time,(15,)])

    # task.append([17,"host",20,(6,9,12,15)])
    
    return task

def generate_tasks(task_count,read_r=1,write_r=1,ndp_r=1,recssd=1,recssd_read=1):
    task_list.clear()

    #生成各自的range
    total_range = read_r+write_r+ndp_r+recssd+recssd_read
    read_range_list = list(range(0,read_r))
    write_range_list = list(range(read_r,read_r+write_r))
    ndp_range_list = list(range(read_r+write_r,read_r+write_r+ndp_r))
    recssd_range_list = list(range(read_r+write_r+ndp_r,read_r+write_r+ndp_r+recssd))
    recssd_read_range_list = list(range(read_r+write_r+ndp_r+recssd,total_range))

    for i in range(task_count): #总共生成多少个任务
        randnum = randint(0,total_range-1)
        if randnum in read_range_list:
            task_list.append(slacker_read_generator())
        elif randnum in write_range_list:
            task_list.append(slacker_write_generator())
        elif randnum in ndp_range_list:
            task_list.append(text_search_generator())
        elif randnum in recssd_range_list:
            task_list.append(generate_recssd_task())
        elif randnum in recssd_read_range_list:
            task_list.append(generate_recssd_read_task())

    #打印每种任务分别多少个
    print("读:",read_count)
    print("写:",write_count)
    print("文本:",text_search_count)
    print("RecSSD:",recssd_count)
    print("RecSSD Read:",recssd_read_count)

print("generate task done")
